//
//  NSEWriter.cpp
//  NSESolver
//
//  Created by Patrick Zulian on 3/25/11.
//  Copyright 2011 ICS - USI - Lugano. All rights reserved.
//


#include "NSEWriter.h"



namespace nsesolver {
    
    
    NSEWriter::NSEWriter(const std::string &path, const CartesianTopology &cart)
    : AbstractWriter(path, ".txt", cart)
    { }
    

   
    void NSEWriter::solverStarted(CFDProblem &problem)
    {
        using std::ofstream;
        using std::string;
        using std::ios;
        
        std::cout << cart.getCommunicator() << " Coords: " <<  cart.getCoordinates() << std::endl;
        
        
        const string ltFile(path + "/local_topology_" + intToStr(cart.getCommunicator().getRank()) + extension);
        
        ofstream os;
        os.open(ltFile.c_str());
        if (os.good()) {
          
            os << problem.IGlobal() << " " << problem.JGlobal();
        }
        
        os.close();
        
        if (!cart.getCommunicator().isRoot()) return;
        
        
        const string tFile(path + "/processor_topology" + extension);
        
        os.open(tFile.c_str());
        if (os.good()) {
            os << cart.getDimensions();
        }
        
        os.close();
        
        
        os.open((path + "/obstacle" + extension).c_str());
        if (os.good()) {
            
            Matrixd obsMat(problem.P().xmax() -1, problem.P().ymax() -1);
            obsMat.allSet(0);
            const Obstacle & obstacle(problem.getBoundaryConditions().getObstacle());
            
            Obstacle::ConstObsCellIter it;
            for (it = obstacle.obsCellBegin(); it != obstacle.obsCellEnd(); ++it) {
                obsMat(it->i, it->j) = it->type;
            }
            os << obsMat;
        }
        
        os.close();
        
        
    }
    
    
    void NSEWriter::solverStep(CFDProblem &problem, const int q )
    {
        using std::ofstream;
        using std::string;
        using std::ios;
        using std::ostringstream;
        
        const Matrixd &p(problem.P()); 
        const Matrixd &u(problem.U()); 
        const Matrixd &v(problem.V());
 
        const string rankStr =  "_" + intToStr(cart.getCommunicator().getRank());
        
        string pFile(path + "/p");
        string uFile(path + "/u");
        string vFile(path + "/v");
        
        pFile += intToStr(q);
        pFile += rankStr;
        pFile += extension;
        
        uFile += intToStr(q);
        uFile += rankStr;
        uFile += extension;
        
        vFile += intToStr(q);
        vFile += rankStr;
        vFile += extension;
        
        Matrixd outM(p.xmax() -1, p.ymax() -1);
        outM.allSet(0);
        
        Range   rangeX(0, outM.xmax() - !isBoundary(East, cart) ), 
                rangeY(0, outM.ymax() - !isBoundary(North, cart) );

        ofstream os;
        os.open(pFile.c_str());
        if (os.good()) {
            auxShift(outM, p, 1, 1);
            os << outM(rangeX, rangeY);
        }
        os.close();
        
        os.open(uFile.c_str());
        if (os.good()) {
            outM.allSet(0);
            auxShift(outM, u, 1, 0);
            os << outM(rangeX, rangeY);
        }
        os.close();
        
        os.open(vFile.c_str());
        if (os.good()) {
            outM.allSet(0);
            auxShift(outM, v, 0, 1);


            os << outM(rangeX, rangeY);
        }
            
    }
    
}
